// 全局变量
let currentTab = 'subscriptions';
let currentPage = 1;
let selectedDownloads = new Set();
let allSubscriptions = []; // 新增：用于存储所有订阅的全局变量
let confirmModalResolver = null; // 用于存储 Promise 的 resolve 函数
let currentSubPage = 1;
let subPageSize = 6;
let subTotal = 0;

// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', function() {
    initializeApp();
});

// 初始化应用
function initializeApp() {
    loadSystemStatus();
    loadSubscriptions();
    loadDownloads();
    loadSystemConfig();
    loadXunleiNASConfig(); // 新增：加载迅雷NAS配置
    loadSystemInfo(); // 加载系统信息

    // 绑定事件监听器
    bindEventListeners();
    
    // 定期更新状态
    setInterval(loadSystemStatus, 30000); // 每30秒更新一次状态
}

// 绑定事件监听器
function bindEventListeners() {
    // 订阅表单提交
    document.getElementById('subscription-form').addEventListener('submit', handleSubscriptionSubmit);
    
    // 编辑表单提交
    document.getElementById('edit-form').addEventListener('submit', handleEditSubmit);
    
    // 状态筛选
    document.getElementById('status-filter').addEventListener('change', function() {
        currentPage = 1;
        loadDownloads();
    });
    
    // 影视名称筛选
    document.getElementById('name-filter').addEventListener('input', function() {
        currentPage = 1;
        loadDownloads();
    });
    
    // 全选下载任务
    document.getElementById('select-all-downloads').addEventListener('change', handleSelectAllDownloads);
    
    // 批量重新下载
    document.getElementById('batch-retry-btn').addEventListener('click', handleBatchRetry);
    
    // 分页按钮
    document.getElementById('prev-page').addEventListener('click', () => {
        if (currentPage > 1) {
            currentPage--;
            loadDownloads();
        }
    });
    
    document.getElementById('next-page').addEventListener('click', () => {
        currentPage++;
        loadDownloads();
    });
    
    // 系统设置
    document.getElementById('scheduler-toggle').addEventListener('change', handleSchedulerToggle);
    document.getElementById('auto-download-toggle').addEventListener('change', handleAutoDownloadToggle);
    document.getElementById('update-interval-btn').addEventListener('click', handleUpdateInterval);
    document.getElementById('xunleinas-form').addEventListener('submit', handleXunleiNASConfigSubmit);
    document.getElementById('confirm-delete-btn').addEventListener('click', () => closeConfirmModal(true));
}

// 切换标签页
function switchTab(tabName) {
    // 隐藏所有标签页内容
    document.querySelectorAll('.tab-content').forEach(content => {
        content.classList.remove('active');
    });
    
    // 重置所有标签按钮样式
    document.querySelectorAll('.tab-button').forEach(button => {
        button.classList.remove('border-blue-500', 'text-blue-600');
        button.classList.add('border-transparent', 'text-gray-500');
    });
    
    // 显示选中的标签页
    document.getElementById(tabName).classList.add('active');
    document.getElementById(`tab-${tabName}`).classList.remove('border-transparent', 'text-gray-500');
    document.getElementById(`tab-${tabName}`).classList.add('border-blue-500', 'text-blue-600');
    
    currentTab = tabName;
    
    // 根据标签页加载相应数据
    switch(tabName) {
        case 'subscriptions':
            loadSubscriptions();
            break;
        case 'downloads':
            loadDownloads();
            break;
        case 'settings':
            loadSystemConfig();
            loadXunleiNASConfig();
            loadSystemInfo(); // 加载系统信息
            break;
        case 'status':
            loadDetailedSystemStatus();
            break;
    }
}

// 加载系统状态
async function loadSystemStatus() {
    try {
        const response = await fetch('/api/system/status');
        const data = await response.json();
        
        if (data.success) {
            updateSystemStatusDisplay(data.data);
        }
    } catch (error) {
        console.error('加载系统状态失败:', error);
    }
}

// 更新系统状态显示
function updateSystemStatusDisplay(status) {
    // 更新状态指示器
    const schedulerStatus = document.getElementById('scheduler-status');
    const schedulerText = document.getElementById('scheduler-text');
    const autoDownloadStatus = document.getElementById('auto-download-status');
    const autoDownloadText = document.getElementById('auto-download-text');
    
    if (status.scheduler_enabled) {
        schedulerStatus.className = 'status-indicator status-active';
        schedulerText.textContent = '运行中';
    } else {
        schedulerStatus.className = 'status-indicator status-inactive';
        schedulerText.textContent = '关闭';
    }
    
    if (status.global_auto_download) {
        autoDownloadStatus.className = 'status-indicator status-active';
        autoDownloadText.textContent = '开启';
    } else {
        autoDownloadStatus.className = 'status-indicator status-inactive';
        autoDownloadText.textContent = '关闭';
    }
    
    // 更新统计数据
    document.getElementById('active-subscriptions').textContent = status.subscriptions.active;
    document.getElementById('pending-downloads').textContent = status.downloads.created_success || 0;
}

// 加载详细系统状态
async function loadDetailedSystemStatus() {
    try {
        const response = await fetch('/api/system/detailed_status');
        const data = await response.json();
        
        if (data.success) {
            updateDetailedStatusDisplay(data.data);
        }
    } catch (error) {
        console.error('加载详细系统状态失败:', error);
    }
}

// 更新详细状态显示
function updateDetailedStatusDisplay(status) {
    // 更新统计卡片
    document.getElementById('stat-subscriptions').textContent = status.subscriptions.total;
    document.getElementById('stat-downloads').textContent = status.downloads.total;
    
    const successRate = status.downloads.total > 0 ? 
        Math.round((status.downloads.created_success / status.downloads.total) * 100) : 0;
    document.getElementById('stat-success-rate').textContent = successRate + '%';
    document.getElementById('stat-today-crawls').textContent = status.crawl_stats.today_crawls;
    
    // 更新系统信息
    if (status.system_info) {
        document.getElementById('cpu-percent').textContent = status.system_info.cpu_percent + '%';
        document.getElementById('cpu-progress').style.width = status.system_info.cpu_percent + '%';
        
        document.getElementById('memory-percent').textContent = status.system_info.memory_percent + '%';
        document.getElementById('memory-progress').style.width = status.system_info.memory_percent + '%';
        
        document.getElementById('disk-percent').textContent = status.system_info.disk_percent + '%';
        document.getElementById('disk-progress').style.width = status.system_info.disk_percent + '%';
    }
    
    // 更新任务状态
    document.getElementById('waiting-count').textContent = status.downloads.waiting_create;
    document.getElementById('created-count').textContent = status.downloads.created_success;
    document.getElementById('duplicate-count').textContent = status.downloads.task_duplicate;
    document.getElementById('failed-count').textContent = status.downloads.created_failed;
}

// 加载系统配置
async function loadSystemConfig() {
    try {
        const response = await fetch('/api/system/config');
        const data = await response.json();
        
        if (data.success) {
            document.getElementById('scheduler-toggle').checked = data.data.scheduler_enabled;
            document.getElementById('auto-download-toggle').checked = data.data.global_auto_download;
            document.getElementById('crawl-interval').value = data.data.crawl_interval;
        }
    } catch (error) {
        console.error('加载系统配置失败:', error);
    }
}

// 处理定时任务开关
async function handleSchedulerToggle(event) {
    const enabled = event.target.checked;
    
    try {
        const response = await fetch('/api/system/config/scheduler', {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ enabled })
        });
        
        const data = await response.json();
        
        if (data.success) {
            showToast(data.message, 'success');
            loadSystemStatus();
        } else {
            showToast(data.message, 'error');
            event.target.checked = !enabled; // 恢复原状态
        }
    } catch (error) {
        showToast('操作失败: ' + error.message, 'error');
        event.target.checked = !enabled; // 恢复原状态
    }
}

// 处理自动下载开关
async function handleAutoDownloadToggle(event) {
    const enabled = event.target.checked;
    
    try {
        const response = await fetch('/api/system/config/global_auto_download', {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ enabled })
        });
        
        const data = await response.json();
        
        if (data.success) {
            showToast(data.message, 'success');
            loadSystemStatus();
        } else {
            showToast(data.message, 'error');
            event.target.checked = !enabled; // 恢复原状态
        }
    } catch (error) {
        showToast('操作失败: ' + error.message, 'error');
        event.target.checked = !enabled; // 恢复原状态
    }
}

// 处理更新间隔
async function handleUpdateInterval() {
    const interval = parseInt(document.getElementById('crawl-interval').value);
    
    if (interval < 1 || interval > 1440) {
        showToast('爬取间隔必须在1-1440分钟之间', 'error');
        return;
    }
    
    try {
        const response = await fetch('/api/system/config/crawl_interval', {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ interval })
        });
        
        const data = await response.json();
        
        if (data.success) {
            showToast(data.message, 'success');
        } else {
            showToast(data.message, 'error');
        }
    } catch (error) {
        showToast('操作失败: ' + error.message, 'error');
    }
}

// 加载订阅列表
async function loadSubscriptions(page = 1) {
    currentSubPage = page;
    try {
        const response = await fetch(`/api/subscriptions?page=${page}&page_size=${subPageSize}`);
        const data = await response.json();
        if (data.success) {
            allSubscriptions = data.data;
            subTotal = data.pagination.total;
            displaySubscriptions(data.data, data.pagination);
        } else {
            showToast('加载订阅列表失败: ' + data.message, 'error');
        }
    } catch (error) {
        showToast('加载订阅列表失败: ' + error.message, 'error');
    }
}

// 显示订阅列表
function displaySubscriptions(subscriptions, pagination) {
    const container = document.getElementById('subscriptions-list');
    const totalElement = document.getElementById('total-subscriptions');
    totalElement.textContent = pagination ? pagination.total : subscriptions.length;
    if (subscriptions.length === 0) {
        container.innerHTML = `
            <div class="text-center py-8 text-gray-500">
                <i class="fas fa-inbox text-4xl mb-4"></i>
                <p>暂无订阅，请添加您的第一个订阅</p>
            </div>
        `;
        document.getElementById('subscriptions-pagination').innerHTML = '';
        return;
    }
    container.innerHTML = subscriptions.map(sub => `
        <div class="subscription-item p-3">
            <div class="flex items-center justify-between">
                <div class="flex-1">
                    <div class="flex items-center mb-1">
                        <i class="fas fa-video mr-2 ${sub.is_active ? 'icon-active' : 'icon-inactive'}"></i>
                        <h4 class="font-medium text-gray-900 text-sm">${sub.name}</h4>
                        <span class="ml-2 px-2 py-0.5 text-xs rounded-full ${getTypeColor(sub.type)}">${sub.site}</span>
                        <span class="ml-2 px-2 py-0.5 text-xs rounded-full ${getTypeColor(sub.type)}">${getTypeText(sub.type)}</span>
                    </div>
                    <div class="text-xs text-gray-600 mb-1">
                        <i class="fas fa-folder mr-1"></i>
                        ${sub.download_directory || '未设置下载目录'}
                    </div>
                    <div class="text-xs text-gray-500 truncate">
                        <i class="fas fa-link mr-1"></i>
                        ${sub.url}
                    </div>
                    <p class="text-xs text-gray-400 mt-0.5">
                        创建: ${formatDateTime(sub.created_at)} | 更新: ${formatDateTime(sub.updated_at)}
                    </p>
                </div>
                <div class="flex items-center space-x-1">
                    <!-- 开启/关闭 按钮 -->
                    <button onclick="toggleSubscriptionStatus(${sub.id}, ${!sub.is_active})"
                            class="px-2 py-1 text-xs rounded-md transition-colors ${sub.is_active ? 'bg-red-100 text-red-700 hover:bg-red-200' : 'bg-green-100 text-green-700 hover:bg-green-200'}">
                        ${sub.is_active ? '<i class="fas fa-toggle-off mr-1"></i>关闭' : '<i class="fas fa-toggle-on mr-1"></i>开启'}
                    </button>
                    <!-- 自动下载按钮 -->
                    <button onclick="toggleAutoDownload(${sub.id}, ${!sub.auto_download})"
                            class="px-2 py-1 text-xs rounded-md transition-colors ${sub.auto_download ? 'bg-red-100 text-red-700 hover:bg-red-200' : 'bg-green-100 text-green-700 hover:bg-green-200'}">
                        <i class="fas fa-download mr-1"></i>${sub.auto_download ? '停止' : '下载'}
                    </button>
                    <!-- 查看下载地址 按钮 -->
                    <button onclick="toggleUrlsDisplay(${sub.id})"
                            class="px-1 py-1 text-xs text-gray-500 hover:text-gray-700">
                        <i class="fas fa-chevron-down"></i>
                    </button>
                    <!-- 三点菜单 -->
                    <div class="dropdown">
                            <button onclick="toggleDropdown(${sub.id})" class="px-1 py-1 text-xs text-gray-500 hover:text-gray-700 rounded-md hover:bg-gray-100">
                                <i class="fas fa-ellipsis-v"></i>
                            </button>
                        <div id="dropdown-${sub.id}" class="dropdown-content">
                            <button onclick="crawlSubscription(${sub.id})">
                                <i class="fas fa-spider mr-2 text-purple-600"></i>
                                手动爬取
                            </button>
                            <button onclick="editSubscription(${sub.id})">
                                <i class="fas fa-edit mr-2 text-blue-600"></i>
                                编辑
                            </button>
                            <button onclick="deleteSubscription(${sub.id})">
                                <i class="fas fa-trash mr-2 text-red-600"></i>
                                删除
                            </button>
                        </div>
                    </div>
                </div>
            </div>
            <div id="urls-${sub.id}" class="collapse-content mt-2">
                <div class="border-t pt-2">
                    <h5 class="font-medium text-gray-900 mb-1 text-sm">
                        <i class="fas fa-list mr-2"></i>下载地址 (${(sub.latest_download_urls || []).length}个)
                    </h5>
                    <div class="max-h-32 overflow-y-auto bg-gray-50 rounded-md p-2">
                        ${(sub.latest_download_urls && sub.latest_download_urls.length > 0) ?
                            sub.latest_download_urls.map(url => `
                                <div class="text-xs text-gray-700 mb-1 break-all">
                                    ${url}
                                </div>
                            `).join('') :
                            '<div class="text-xs text-gray-500">暂无下载地址</div>'
                        }
                    </div>
                </div>
            </div>
        </div>
    `).join('');
    renderSubPagination(pagination);
}

function renderSubPagination(pagination) {
    const pagDiv = document.getElementById('subscriptions-pagination');
    if (!pagination) { pagDiv.innerHTML = ''; return; }
    const { page, page_size, total } = pagination;
    const totalPages = Math.max(1, Math.ceil(total / page_size));
    let html = '<div class="flex items-center justify-center mt-6">';
    html += `<button class=\"px-3 py-1 mx-1 rounded-md border ${page === 1 ? 'bg-gray-200 text-gray-400 cursor-not-allowed' : 'bg-white text-gray-700 hover:bg-blue-50'}\" ${page === 1 ? 'disabled' : ''} onclick=\"loadSubscriptions(${page-1})\">上一页</button>`;
    // 页码按钮（简化，最多显示5页）
    let start = Math.max(1, page-2), end = Math.min(totalPages, page+2);
    if (page <= 3) end = Math.min(5, totalPages);
    if (page >= totalPages-2) start = Math.max(1, totalPages-4);
    for (let i = start; i <= end; i++) {
        html += `<button class=\"px-3 py-1 mx-1 rounded-md border ${i === page ? 'bg-blue-500 text-white font-bold' : 'bg-white text-gray-700 hover:bg-blue-50'}\" onclick=\"loadSubscriptions(${i})\">${i}</button>`;
    }
    html += `<button class=\"px-3 py-1 mx-1 rounded-md border ${page === totalPages ? 'bg-gray-200 text-gray-400 cursor-not-allowed' : 'bg-white text-gray-700 hover:bg-blue-50'}\" ${page === totalPages ? 'disabled' : ''} onclick=\"loadSubscriptions(${page+1})\">下一页</button>`;
    html += '</div>';
    pagDiv.innerHTML = html;
}

// 处理订阅表单提交
async function handleSubscriptionSubmit(event) {
    event.preventDefault();
    
    const formData = {
        name: document.getElementById('sub-name').value,
        url: document.getElementById('sub-url').value,
        type: document.getElementById('sub-type').value,
        site: document.getElementById('sub-site').value,
        download_directory: document.getElementById('sub-directory').value
    };
    
    // 校验根域名和site
    if (!validateDomainWithSite(formData.url, formData.site)) {
        showToast('订阅地址根域名与订阅网站不一致！', 'error');
        return;
    }

    try {
        const response = await fetch('/api/subscriptions', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(formData)
        });

        const data = await response.json();

        if (data.success) {
            showToast('订阅添加成功', 'success');
            document.getElementById('subscription-form').reset();
            document.getElementById('sub-directory').value = '/'; // 重置默认值
            loadSubscriptions();
            loadSystemStatus();
        } else {
            showToast('添加订阅失败: ' + data.message, 'error');
        }
    } catch (error) {
        showToast('添加订阅失败: ' + error.message, 'error');
    }
}

// 切换订阅状态
async function toggleSubscriptionStatus(id, isActive) {
    try {
        const response = await fetch(`/api/subscriptions/${id}/status`, {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ is_active: isActive })
        });
        
        const data = await response.json();
        
        if (data.success) {
            showToast(data.message, 'success');
            loadSubscriptions();
            loadSystemStatus();
        } else {
            showToast(data.message, 'error');
        }
    } catch (error) {
        showToast('操作失败: ' + error.message, 'error');
    }
}

// 切换自动下载
async function toggleAutoDownload(id, autoDownload) {
    try {
        const response = await fetch(`/api/subscriptions/${id}/auto_download`, {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ auto_download: autoDownload })
        });
        
        const data = await response.json();
        
        if (data.success) {
            showToast(data.message, 'success');
            loadSubscriptions();
        } else {
            showToast(data.message, 'error');
        }
    } catch (error) {
        showToast('操作失败: ' + error.message, 'error');
    }
}

// 手动爬取订阅
async function crawlSubscription(id) {
    try {
        const response = await fetch(`/api/subscriptions/${id}/crawl`, {
            method: 'POST'
        });
        
        const data = await response.json();
        
        if (data.success) {
            showToast(data.message, 'success');
            loadSubscriptions();
            loadDownloads();
        } else {
            showToast(data.message, 'error');
        }
    } catch (error) {
        showToast('爬取失败: ' + error.message, 'error');
    }
}

// 编辑订阅 (修改此函数)
function editSubscription(id) {
    // 从全局变量 allSubscriptions 中查找对应的订阅
    const sub = allSubscriptions.find(s => s.id === id);

    if (!sub) {
        showToast('获取订阅信息失败: 订阅不存在', 'error');
        return;
    }

    // 填充编辑模态框的表单字段
    document.getElementById('edit-id').value = sub.id;
    document.getElementById('edit-name').value = sub.name;
    document.getElementById('edit-url').value = sub.url;
    document.getElementById('edit-type').value = sub.type;
    document.getElementById('edit-directory').value = sub.download_directory;
    document.getElementById('edit-site').value = sub.site || 'dygod';

    // 显示编辑模态框
    document.getElementById('edit-modal').classList.add('show');
}


// 处理编辑表单提交
async function handleEditSubmit(event) {
    event.preventDefault();
    
    const id = document.getElementById('edit-id').value;
    const formData = {
        name: document.getElementById('edit-name').value,
        url: document.getElementById('edit-url').value,
        type: document.getElementById('edit-type').value,
        site: document.getElementById('edit-site').value,
        download_directory: document.getElementById('edit-directory').value
    };

    // 校验根域名和site
    if (!validateDomainWithSite(formData.url, formData.site)) {
        showToast('订阅地址根域名与订阅网站不一致！', 'error');
        return;
    }

    try {
        const response = await fetch(`/api/subscriptions/${id}`, {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(formData)
        });

        const data = await response.json();

        if (data.success) {
            showToast('订阅更新成功', 'success');
            closeEditModal();
            loadSubscriptions();
        } else {
            showToast('更新订阅失败: ' + data.message, 'error');
        }
    } catch (error) {
        showToast('更新订阅失败: ' + error.message, 'error');
    }
}

// 删除订阅
async function deleteSubscription(id) {
    // 从全局变量 allSubscriptions 中查找对应的订阅
    const subToDelete = allSubscriptions.find(s => s.id === id);

    if (!subToDelete) {
        showToast('删除失败: 未找到该订阅信息', 'error');
        return;
    }

    // 检查订阅是否活跃
    if (subToDelete.is_active) {
        showToast('请先关闭订阅才能删除！', 'error'); // 友好的提示
        return;
    }
    const confirmed = await showConfirmModal('确定要删除这个订阅吗？此操作不可恢复。');

    if (!confirmed) {
        // 用户点击了取消或关闭按钮
        return;
    }

    try {
        const response = await fetch(`/api/subscriptions/${id}`, {
            method: 'DELETE'
        });

        const data = await response.json();

        if (data.success) {
            showToast('订阅删除成功', 'success');
            loadSubscriptions();
            loadSystemStatus();
        } else {
            showToast('删除订阅失败: ' + data.message, 'error');
        }
    } catch (error) {
        showToast('删除订阅失败: ' + error.message, 'error');
    }
}

// 加载下载任务
async function loadDownloads() {
    const statusFilter = document.getElementById('status-filter').value;
    const nameFilter = document.getElementById('name-filter').value.trim();
    const params = new URLSearchParams({
        status: statusFilter,
        name: nameFilter,
        page: currentPage,
        per_page: 10
    });
    try {
        const response = await fetch(`/api/downloads?${params.toString()}`);
        const data = await response.json();
        if (data.success) {
            displayDownloads(data.data.tasks, data.data.pagination);
        } else {
            showToast('加载下载任务失败: ' + data.message, 'error');
        }
    } catch (error) {
        showToast('加载下载任务失败: ' + error.message, 'error');
    }
}

// 显示下载任务
function displayDownloads(tasks, pagination) {
    const tbody = document.getElementById('downloads-list');
    
    if (tasks.length === 0) {
        tbody.innerHTML = `
            <tr>
                <td colspan="6" class="px-4 py-8 text-center text-gray-500">
                    <i class="fas fa-inbox text-4xl mb-4"></i>
                    <p>暂无下载任务</p>
                </td>
            </tr>
        `;
    } else {
        tbody.innerHTML = tasks.map(task => {
            // 只展示 dn= 后的内容
            let dnValue = '';
            try {
                const urlObj = new URL(task.url);
                const dnParam = urlObj.searchParams.get('dn');
                dnValue = dnParam || task.url;
            } catch (e) {
                // 不是标准URL，尝试手动解析
                const match = task.url.match(/[?&]dn=([^&]+)/);
                dnValue = match ? decodeURIComponent(match[1]) : task.url;
            }
            return `
            <tr class="hover:bg-gray-50">
                <td class="px-6 py-2 whitespace-nowrap">
                    <input type="checkbox" class="download-checkbox rounded" value="${task.id}" 
                           onchange="handleDownloadSelection(${task.id}, this.checked)">
                </td>
                <td class="px-6 py-2 whitespace-nowrap">
                    <div class="text-sm font-medium text-gray-900">${task.name}</div>
                </td>
                <td class="px-6 py-2 whitespace-nowrap">
                    <div class="text-sm text-gray-900 break-all max-w-xs">${task.directory}</div>
                </td>
                <td class="px-6 py-2">
                    <div class="text-sm text-blue-700 underline break-all max-w-xs cursor-pointer" title="点击复制下载地址" onclick="copyDownloadUrl('${encodeURIComponent(task.url)}')">${dnValue}</div>
                </td>
                <td class="px-6 py-2 whitespace-nowrap">
                    <span class="status-indicator ${getStatusClass(task.status)}"></span>
                    <span class="text-sm text-gray-900">${getStatusText(task.status)}</span>
                </td>
                <td class="px-6 py-2 whitespace-nowrap text-sm text-gray-500">
                    ${formatDateTime(task.created_at)}
                </td>
                <td class="px-6 py-2 whitespace-nowrap text-sm font-medium">
                    <button onclick="retryDownload(${task.id})" 
                            class="text-blue-600 hover:text-blue-900">重新下载</button>
                </td>
            </tr>
            `;
        }).join('');
    }
    
    // 更新分页信息
    updatePagination(pagination);
    
    // 更新选择状态
    updateBatchRetryButton();
}

// 更新分页信息
function updatePagination(pagination) {
    document.getElementById('page-start').textContent = ((pagination.page - 1) * pagination.per_page + 1);
    document.getElementById('page-end').textContent = Math.min(pagination.page * pagination.per_page, pagination.total);
    document.getElementById('total-downloads').textContent = pagination.total;
    
    document.getElementById('prev-page').disabled = !pagination.has_prev;
    document.getElementById('next-page').disabled = !pagination.has_next;
    // 新增：显示当前页/总页数
    document.getElementById('page-info').textContent = `第 ${pagination.page} / ${pagination.pages} 页`;
}

// 处理下载任务选择
function handleDownloadSelection(taskId, checked) {
    if (checked) {
        selectedDownloads.add(taskId);
    } else {
        selectedDownloads.delete(taskId);
    }
    updateBatchRetryButton();
}

// 处理全选下载任务
function handleSelectAllDownloads(event) {
    const checkboxes = document.querySelectorAll('.download-checkbox');
    checkboxes.forEach(checkbox => {
        checkbox.checked = event.target.checked;
        handleDownloadSelection(parseInt(checkbox.value), checkbox.checked);
    });
}

// 更新批量重新下载按钮状态
function updateBatchRetryButton() {
    const button = document.getElementById('batch-retry-btn');
    button.disabled = selectedDownloads.size === 0;
    button.textContent = selectedDownloads.size > 0 ? 
        `批量重新下载 (${selectedDownloads.size})` : '批量重新下载';
}

// 重新下载单个任务
async function retryDownload(taskId) {
    const confirmed = await showConfirmModal('确定要重新下载该任务吗？', '确认', 'btn-primary');
    if (!confirmed) {
        return;
    }
    try {
        const response = await fetch(`/api/downloads/${taskId}/retry`, {
            method: 'POST'
        });
        
        const data = await response.json();
        
        if (data.success) {
            showToast(data.message, 'success');
            // 延迟一点时间再刷新，确保队列处理完成
            setTimeout(() => {
                loadDownloads();
            }, 1000);
        } else {
            showToast('重新下载失败: ' + data.message, 'error');
        }
    } catch (error) {
        showToast('重新下载失败: ' + error.message, 'error');
    }
}

// 批量重新下载
async function handleBatchRetry() {
    if (selectedDownloads.size === 0) {
        showToast('请选择要重新下载的任务', 'error');
        return;
    }
    const confirmed = await showConfirmModal('确定要批量重新下载选中的任务吗？', '确认', 'btn-primary');
    if (!confirmed) {
        return;
    }
    try {
        const response = await fetch('/api/downloads/retry', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                task_ids: Array.from(selectedDownloads)
            })
        });
        
        const data = await response.json();
        
        if (data.success) {
            showToast(data.message, 'success');
            selectedDownloads.clear();
            document.getElementById('select-all-downloads').checked = false;
            // 延迟一点时间再刷新，确保队列处理完成
            setTimeout(() => {
                loadDownloads();
            }, 1000);
        } else {
            showToast('批量重新下载失败: ' + data.message, 'error');
        }
    } catch (error) {
        showToast('批量重新下载失败: ' + error.message, 'error');
    }
}

// 工具函数
function getTypeColor(type) {
    const colors = {
        'movie': 'bg-blue-100 text-blue-800',
        'tv': 'bg-indigo-100 text-indigo-800',
        'anime': 'bg-purple-100 text-purple-800',
        'variety': 'bg-yellow-100 text-yellow-800',
        'documentary': 'bg-gray-100 text-gray-800'
    };
    return colors[type] || 'bg-gray-100 text-gray-800';
}

function getTypeText(type) {
    const texts = {
        'movie': '电影',
        'tv': '电视剧',
        'anime': '动漫',
        'variety': '综艺',
        'documentary': '纪录片'
    };
    return texts[type] || type;
}

function getStatusClass(status) {
    const classes = {
        'waiting_create': 'status-waiting',
        'created_success': 'status-created',
        'created_failed': 'status-failed',
        'task_duplicate': 'status-duplicate'
    };
    return classes[status] || 'status-inactive';
}

function getStatusText(status) {
    const texts = {
        'waiting_create': '等待创建',
        'created_success': '创建成功',
        'created_failed': '创建失败',
        'task_duplicate': '任务重复'
    };
    return texts[status] || status;
}

function formatDateTime(dateString) {
    if (!dateString) return '-';
    const date = new Date(dateString);
    return date.toLocaleString('zh-CN');
}
// **新增：下载目录校验函数**
function validateDownloadDirectory(directory) {
    // 校验规则：
    // 1. 必须以 '/' 开头
    // 2. 不能包含空格、单引号 (')、双引号 (")
    // 3. 允许包含字母、数字、下划线、连字符、点和斜杠
    // 4. 避免连续的斜杠 //
    const regex = /^\/[\u4e00-\u9fa5a-zA-Z0-9\/\._-]*$/; // 允许 /a/b/c.d-e_f 这样的路径，并新增支持中文

    if (!directory) {
        showToast('下载目录不能为空', 'error');
        return false;
    }

    if (directory.includes(' ') || directory.includes("'") || directory.includes('"')) {
        showToast('下载目录不能包含空格、单引号或双引号', 'error');
        return false;
    }

    if (!regex.test(directory)) {
        showToast('下载目录格式不正确，请使用 /xxx/xxxx 类似结构，且不能包含特殊字符', 'error');
        return false;
    }

    return true;
}

// 模态框相关函数
function closeEditModal() {
    document.getElementById('edit-modal').classList.remove('show');
}
// 显示自定义确认模态框
function showConfirmModal(message, confirmText = '确认', confirmClass = 'btn-danger') {
    return new Promise((resolve) => {
        confirmModalResolver = resolve; // 存储 resolve 函数
        document.getElementById('confirm-message').textContent = message; // 设置提示信息
        // 设置按钮文字和样式
        const btn = document.getElementById('confirm-delete-btn');
        btn.textContent = confirmText;
        btn.className = `flex-1 ${confirmClass} text-white py-2 px-4 rounded-md font-medium`;
        document.getElementById('confirm-modal').classList.add('show'); // 显示模态框
    });
}

// 关闭自定义确认模态框
function closeConfirmModal(result) {
    document.getElementById('confirm-modal').classList.remove('show'); // 隐藏模态框
    if (confirmModalResolver) {
        confirmModalResolver(result); // 调用 resolve 函数，传递结果 (true/false)
        confirmModalResolver = null; // 重置 resolver
    }
}

// 下拉菜单相关函数
function toggleDropdown(id) {
    const dropdown = document.getElementById(`dropdown-${id}`).parentElement;
    dropdown.classList.toggle('show');
    
    // 点击其他地方关闭下拉菜单
    document.addEventListener('click', function(event) {
        if (!dropdown.contains(event.target)) {
            dropdown.classList.remove('show');
        }
    });
}

function toggleUrlsDisplay(id) {
    const urlsDiv = document.getElementById(`urls-${id}`);
    urlsDiv.classList.toggle('expanded');
}

// Toast 通知函数
function showToast(message, type = 'info') {
    const toast = document.getElementById('toast');
    const messageElement = document.getElementById('toast-message');
    
    messageElement.textContent = message;
    toast.className = `toast ${type}`;
    toast.classList.add('show');
    
    setTimeout(() => {
        toast.classList.remove('show');
    }, 3000);
}
// 加载迅雷NAS配置
async function loadXunleiNASConfig() {
    try {
        const response = await fetch('/api/system/xunlei_nas_config');
        const data = await response.json();

        if (data.success) {
            document.getElementById('xunleinas-host').value = data.data.host || '';
            document.getElementById('xunleinas-credential').value = data.data.credential || '';
            document.getElementById('xunleinas-initial-dir-id').value = data.data.initial_dir_id || '';
            document.getElementById('xunleinas-device-space-id').value = data.data.device_space_id || '';

            // 更新状态指示器
            updateXunleiStatusIndicator(data.data);
        } else {
            console.error('加载迅雷NAS配置失败:', data.message);
            updateXunleiStatusIndicator(null);
        }
    } catch (error) {
        console.error('加载迅雷NAS配置失败:', error);
        updateXunleiStatusIndicator(null);
    }
}

// 更新迅雷NAS状态指示器
function updateXunleiStatusIndicator(config) {
    const indicator = document.getElementById('xunlei-status-indicator');
    const icon = document.getElementById('xunlei-status-icon');
    const text = document.getElementById('xunlei-status-text');
    const time = document.getElementById('xunlei-status-time');

    if (config && config.host && config.credential) {
        indicator.className = 'bg-green-50 border border-green-200 rounded-lg p-3 mb-4';
        icon.className = 'fas fa-check-circle text-green-600';
        text.textContent = '已配置';
        text.className = 'text-sm font-medium text-green-800';
        time.textContent = config.last_updated ? `最后更新：${config.last_updated}` : '';
    } else {
        indicator.className = 'bg-gray-50 border border-gray-200 rounded-lg p-3 mb-4';
        icon.className = 'fas fa-exclamation-circle text-gray-600';
        text.textContent = '未配置';
        text.className = 'text-sm font-medium text-gray-800';
        time.textContent = '';
    }
}

// 处理迅雷NAS配置保存
async function handleXunleiNASConfigSubmit(event) {
    event.preventDefault();

    const host = document.getElementById('xunleinas-host').value.trim();
    const credential = document.getElementById('xunleinas-credential').value.trim();
    const initialDirId = document.getElementById('xunleinas-initial-dir-id').value.trim();
    const deviceSpaceId = document.getElementById('xunleinas-device-space-id').value.trim();

    // 前端校验：参数不能为空
    if (!host) {
        showToast('主机地址不能为空', 'error');
        return;
    }
    if (!credential) {
        showToast('授权凭证不能为空', 'error');
        return;
    }
    if (!initialDirId) {
        showToast('初始目录ID不能为空', 'error');
        return;
    }
    if (!deviceSpaceId) {
        showToast('设备空间ID不能为空', 'error');
        return;
    }

    try {
        const response = await fetch('/api/system/xunlei_nas_config', {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                host: host,
                credential: credential,
                initial_dir_id: initialDirId,
                device_space_id: deviceSpaceId
            })
        });

        const data = await response.json();

        if (data.success) {
            showToast(data.message, 'success');
            // 重新加载配置以更新状态指示器
            loadXunleiNASConfig();
        } else {
            showToast(data.message, 'error');
        }
    } catch (error) {
        showToast('保存迅雷NAS配置失败: ' + error.message, 'error');
    }
}

// 测试迅雷NAS连接
async function testXunleiConnection() {
    const host = document.getElementById('xunleinas-host').value.trim();
    const credential = document.getElementById('xunleinas-credential').value.trim();

    if (!host || !credential) {
        showToast('请先填写主机地址和授权凭证', 'error');
        return;
    }

    showToast('正在测试连接...', 'info');

    try {
        const response = await fetch('/api/system/xunlei_nas_test', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                host: host,
                credential: credential
            })
        });

        const data = await response.json();

        if (data.success) {
            showToast('连接测试成功！迅雷NAS响应正常', 'success');
        } else {
            showToast('连接测试失败：' + data.message, 'error');
        }
    } catch (error) {
        showToast('连接测试失败：' + error.message, 'error');
    }
}

// 切换密码显示
function togglePassword(inputId) {
    const input = document.getElementById(inputId);
    const icon = input.nextElementSibling.querySelector('i');

    if (input.type === 'password') {
        input.type = 'text';
        icon.classList.remove('fa-eye');
        icon.classList.add('fa-eye-slash');
    } else {
        input.type = 'password';
        icon.classList.remove('fa-eye-slash');
        icon.classList.add('fa-eye');
    }
}

// 加载系统信息（其他设置页面）
async function loadSystemInfo() {
    try {
        // 获取序列号
        let serialNumber = ''; // 默认值
        let created_at = '';
        try {
            const serialResponse = await fetch('/api/system/serial');
            const serialData = await serialResponse.json();
            if (serialData.success) {
                serialNumber = serialData.data.serial;
                created_at = serialData.data.created_at;
            }
        } catch (error) {
            console.error('获取序列号失败:', error);
        }

        // 获取网络信息
        let networkInfo = {
            localIp: '获取失败',
            publicIp: '获取失败',
            networkStatus: '异常',
            serverPort: '5000'
        };
        
        try {
            const networkResponse = await fetch('/api/system/network_info');
            const networkData = await networkResponse.json();
            if (networkData.success) {
                networkInfo = {
                    localIp: networkData.data.local_ip,
                    publicIp: networkData.data.public_ip,
                    networkStatus: networkData.data.network_status,
                    serverPort: networkData.data.port
                };
            }
        } catch (error) {
            console.error('获取网络信息失败:', error);
        }

        const systemInfo = {
            software: {
                version: 'v3.1.0',
                author: 'ufohacker@foxmail.com',
                buildDate: '2025-7',
                license: 'MIT License'
            },
            serial: {
                deviceSerial: serialNumber,
                activationStatus: '已激活',
                activationDate: created_at,
                expiryDate: '永久有效'
            },
            network: networkInfo
        };

        updateSystemInfoDisplay(systemInfo);
        
    } catch (error) {
        console.error('加载系统信息失败:', error);
        showToast('加载系统信息失败', 'error');
    }
}

// 更新系统信息显示
function updateSystemInfoDisplay(info) {
    // 软件信息
    document.getElementById('software-version').textContent = info.software.version;
    document.getElementById('software-author').textContent = info.software.author;
    document.getElementById('build-date').textContent = info.software.buildDate;
    document.getElementById('license').textContent = info.software.license;
    
    // 序列号信息
    document.getElementById('device-serial').textContent = info.serial.deviceSerial;
    document.getElementById('activation-status').textContent = info.serial.activationStatus;
    document.getElementById('activation-date').textContent = info.serial.activationDate;
    document.getElementById('expiry-date').textContent = info.serial.expiryDate;
    
    // 网络信息
    document.getElementById('local-ip').textContent = info.network.localIp;
    document.getElementById('public-ip').textContent = info.network.publicIp;
    
    // 网络状态显示，根据状态设置不同颜色
    const networkStatusElement = document.getElementById('network-status');
    networkStatusElement.textContent = info.network.networkStatus;
    if (info.network.networkStatus === '正常') {
        networkStatusElement.className = 'font-medium text-green-600 ml-2';
    } else {
        networkStatusElement.className = 'font-medium text-red-600 ml-2';
    }
    
    document.getElementById('server-port').textContent = info.network.serverPort;
}

// 新增：根域名与site校验函数
function validateDomainWithSite(url, site) {
    try {
        const domainMap = { dygod: 'dygod.net', meijutt: 'meijutt.tv' };
        const a = document.createElement('a');
        a.href = url;
        const hostname = a.hostname;
        const urlDomain = hostname.split('.').slice(-2).join('.');
        return urlDomain === domainMap[site];
    } catch (e) {
        return false;
    }
}

// 在文件末尾添加复制函数
function copyDownloadUrl(encodedUrl) {
    const url = decodeURIComponent(encodedUrl);
    if (navigator.clipboard) {
        navigator.clipboard.writeText(url).then(() => {
            showToast('下载地址已复制', 'success');
        }, () => {
            showToast('复制失败，请手动复制', 'error');
        });
    } else {
        // 兼容旧浏览器
        const textarea = document.createElement('textarea');
        textarea.value = url;
        document.body.appendChild(textarea);
        textarea.select();
        try {
            document.execCommand('copy');
            showToast('下载地址已复制', 'success');
        } catch (err) {
            showToast('复制失败，请手动复制', 'error');
        }
        document.body.removeChild(textarea);
    }
}




